package com.power.using.myapplication.okhttp;

import com.orhanobut.logger.Logger;
import com.power.using.myapplication.okhttp.sources.CacheInterceptor;
import com.power.using.myapplication.okhttp.sources.HeaderInterceptor;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

import okhttp3.Cache;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * Created by 聪明一只哈 on 2019/9/20.
 * Time: 2019/9/20  14:31
 */
public class HttpNetWorkUtil {

    //防止多个线程同时访问
    private volatile static HttpNetWorkUtil instance;
    private static OkHttpClient okHttpClient;


    private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();
    // 使用getCacheDir()来作为缓存文件的存放路径（/data/data/包名/cache） ，
// 如果你想看到缓存文件可以临时使用 getExternalCacheDir()（/sdcard/Android/data/包名/cache）。
    private static File cacheFile;
    private static Cache cache;
    private String responseStr;


    private HttpNetWorkUtil() {

        okHttpClient = new OkHttpClient();
        okHttpClient.newBuilder()
                .addInterceptor(new HeaderInterceptor())
                .addNetworkInterceptor(new CacheInterceptor())
                .connectTimeout(10, TimeUnit.SECONDS)
                .readTimeout(10,TimeUnit.SECONDS)
                .writeTimeout(10,TimeUnit.SECONDS)
                .cookieJar(new CookieJar() {
                    @Override
                    public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
                        cookieStore.put(url.host(),cookies);
                    }

                    @Override
                    public List<Cookie> loadForRequest(HttpUrl url) {
                        //自动管理Cookie发送Request都不用管Cookie这个参数也不用去response获取新Cookie什么的了。
                        // 还能通过cookieStore获取当前保存的Cookie。
                        List<Cookie> cookies = cookieStore.get(url.host());
                        return cookies==null?cookies:new ArrayList<Cookie>();
                    }
                });

    }

    public static  HttpNetWorkUtil getInstance(){
        if(instance==null){

            synchronized (HttpNetWorkUtil.class){
                if(instance==null){
                    instance=new HttpNetWorkUtil();
                }
            }

        }
        return instance;
    }

    /**
     * get请求，同步方式
     * @param url
     * @return String
     */
    public String getStringSync(String url){
        Request request = new Request.Builder()
                .url(url)
                .build();
        Call call = okHttpClient.newCall(request);
        try {
            Response response = call.execute();
            String resultStr = response.body().string();
            return resultStr;
        } catch (IOException e) {
            e.printStackTrace();
            Logger.e("GET同步请求解析为String异常" + e.toString());
        }
        return null;
    }

    /**
     * get请求，同步方式，
     * @param url
     * @return byte数组
     */
    public byte[] getByteArraySync(String url){

        Request request = new Request.Builder()
                .url(url)
                .build();
        Call call = okHttpClient.newCall(request);

        try {
            Response response = call.execute();
            byte[] resultBytes = response.body().bytes();
            return resultBytes;
        } catch (IOException e) {
            Logger.e("GET同步请求解析为byte数组异常" + e.toString());
            e.printStackTrace();
        }
        return null;
    }


    /**
     * get请求，同步方式
     * @param url
     * @return InputStream
     */
    public InputStream getInputStreamSync(String url){

        Request request = new Request.Builder()
                .url(url)
                .build();
        Call call = okHttpClient.newCall(request);

        try {
            Response response = call.execute();
            InputStream responseStream = response.body().byteStream();
            return responseStream;
        } catch (IOException e) {
            Logger.e("GET同步请求解析为String异常" + e.toString());
            e.printStackTrace();
        }
        return null;
    }


    /**
     * get请求，同步请求
     * @param url
     * @return 字符输入流
     */
    public Reader getCharReaderSync(String url){

        Request request = new Request.Builder()
                .url(url)
                .build();

        Call call = okHttpClient.newCall(request);

        try {
            Response response = call.execute();
            Reader resultCharStream = response.body().charStream();
            return resultCharStream;
        } catch (IOException e) {
            Logger.e("GET同步请求解析为Reader异常" + e.toString());
            e.printStackTrace();
        }


        return null;
    }

    /**
     * get请求，异步请求，无参数
     * @param url
     * @return String
     */
    public void getStringWithoutParamsAsync(String url, final CustomCallBack callBack){

        final Request request = new Request.Builder()
                .url(url)
                .build();
        Call call = okHttpClient.newCall(request);
        try {
            callBack.onBefore(request);
            call.enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    callBack.requestFailure(request,e);
                }
                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    responseStr = response.body().string();
                    try{
                        callBack.requestSuccess(responseStr);
                    }catch (Exception e){
                        Logger.e("GET异步请求为String解析异常失败" + e.toString());
                        e.printStackTrace();
                    }finally {
                        callBack.onAfter();
                    }
                }

            });


        }catch (Exception e){
            Logger.e("GET异步请求解析为String异常" + e.toString());
            e.printStackTrace();
        }

    }



}
